home *** CD-ROM | disk | FTP | other *** search
- /*
- * mcxt.c --
- * POSTGRES memory context code.
- */
-
- #include <stdio.h> /* XXX for printf debugging */
-
- #include "tmp/c.h"
-
- RcsId("$Header: /private/postgres/src/utils/mmgr/RCS/mcxt.c,v 1.15 1991/11/12 20:20:29 mer Exp $");
-
- #include "utils/memutils.h"
- #include "utils/module.h"
- #include "utils/excid.h"
-
- #include "nodes/mnodes.h"
- #include "nodes/nodes.h"
- #include "tags.h" /* for classTag */
-
- #include "utils/mcxt.h"
- #include "utils/log.h"
-
- #include "utils/palloc.h"
-
- extern void bcopy(); /* XXX use header */
-
- #undef MemoryContextAlloc
- #undef MemoryContextFree
- #undef malloc
- #undef free
-
- /*
- * Global State
- */
- static Count MemoryContextEnableCount = 0;
- #define MemoryContextEnabled (MemoryContextEnableCount > 0)
-
- static OrderedSetData ActiveGlobalMemorySetData; /* uninitialized */
- #define ActiveGlobalMemorySet (&ActiveGlobalMemorySetData)
-
- MemoryContext CurrentMemoryContext = NULL;
-
- /*
- * description of allocated memory representation goes here
- */
-
- #define PSIZE(PTR) (*((int32 *)(PTR) - 1))
- #define PSIZEALL(PTR) (*((int32 *)(PTR) - 1) + sizeof (int32))
- #define PSIZESKIP(PTR) ((char *)((int32 *)(PTR) + 1))
- #define PSIZEFIND(PTR) ((char *)((int32 *)(PTR) - 1))
- #define PSIZESPACE(LEN) ((LEN) + sizeof (int32))
-
- /*
- * AllocSizeIsValid --
- * True iff 0 < size and size <= MaxAllocSize.
- */
- #define AllocSizeIsValid(size) SizeIsInBounds(size, MaxAllocSize)
-
- /*
- * PRIVATE DEFINITIONS
- */
-
- /*
- * GlobalMemory
- */
-
- /*
- * GlobalMemoryAlloc --
- * Returns pointer to aligned space in the global context.
- *
- * Exceptions:
- * ExhaustedMemory if allocation fails.
- */
- static
- Pointer
- GlobalMemoryAlloc ARGS((
- GlobalMemory this,
- Size size
- ));
-
- /*
- * GlobalMemoryFree --
- * Frees allocated memory in the global context.
- *
- * Exceptions:
- * BadContextErr if current context is not the global context.
- * BadArgumentsErr if pointer is invalid.
- */
- static
- void
- GlobalMemoryFree ARGS((
- GlobalMemory this,
- Pointer pointer
- ));
-
- /*
- * GlobalMemoryRealloc --
- * Returns pointer to aligned space in the global context.
- *
- * Note:
- * Memory associated with the pointer is freed before return.
- *
- * Exceptions:
- * BadContextErr if current context is not the global context.
- * BadArgumentsErr if pointer is invalid.
- * NoMoreMemoryErr if allocation fails.
- */
- static
- Pointer
- GlobalMemoryRealloc ARGS((
- GlobalMemory this,
- Pointer pointer,
- Size size
- ));
-
- /*
- * GlobalMemoryGetName --
- * Returns name string for context.
- *
- * Exceptions:
- * ???
- */
- static
- String
- GlobalMemoryGetName ARGS((
- GlobalMemory this
- ));
-
- /*
- * GlobalMemoryDump --
- * Dumps global memory context for debugging.
- *
- * Exceptions:
- * ???
- */
- static
- void
- GlobalMemoryDump ARGS((
- GlobalMemory this
- ));
-
- /*
- * DumpGlobalMemories --
- * Dumps all global memory contexts for debugging.
- *
- * Exceptions:
- * ???
- */
- static
- void
- DumpGlobalMemories ARGS((void));
-
-
- /*
- * Global Memory Methods
- */
-
- static MemoryContextMethodsData GlobalContextMethodsData = {
- GlobalMemoryAlloc, /* Pointer (*)(this, uint32) palloc */
- GlobalMemoryFree, /* void (*)(this, Pointer) pfree */
- GlobalMemoryRealloc, /* Pointer (*)(this, Pointer) repalloc */
- GlobalMemoryGetName, /* String (*)(this) getName */
- GlobalMemoryDump /* void (*)(this) dump */
- };
-
- /*
- * Note:
- * TopGlobalMemory is handled specially because of bootstrapping.
- */
- /* extern bool EqualGlobalMemory(); */
-
- static classObj(GlobalMemory) TopGlobalMemoryData = {
- classTag(GlobalMemory), /* NodeTag tag */
- PrintGlobalMemory, /* (print function) */
- NULL, /* (equal function) */
- NULL, /* copy function */
- &GlobalContextMethodsData, /* ContextMethods method */
- { 0 }, /* uninitialized */ /* OrderedSetData allocSetD */
- "TopGlobal", /* String name */
- { 0 } /* uninitialized */ /* OrderedElemData elemD */
- };
-
-
- MemoryContext TopMemoryContext = (MemoryContext)&TopGlobalMemoryData;
-
-
- /*
- * Module State
- */
-
- void
- EnableMemoryContext(on)
- bool on;
- {
- static bool processing = false;
-
- AssertState(!processing);
- AssertArg(BoolIsValid(on));
-
- if (BypassEnable(&MemoryContextEnableCount, on)) {
- return;
- }
-
- processing = true;
-
- if (on) { /* initialize */
- /* initialize TopGlobalMemoryData.setData */
- AllocSetInit(&TopGlobalMemoryData.setData, DynamicAllocMode,
- (Size)0);
-
- /* make TopGlobalMemoryData member of ActiveGlobalMemorySet */
- OrderedSetInit(ActiveGlobalMemorySet,
- offsetof(classObj(GlobalMemory), elemData));
- OrderedElemPushInto(&TopGlobalMemoryData.elemData,
- ActiveGlobalMemorySet);
-
- /* initialize CurrentMemoryContext */
- CurrentMemoryContext = TopMemoryContext;
-
- } else { /* cleanup */
- GlobalMemory context;
-
- /* walk the list of allocations */
- while (PointerIsValid(context = (GlobalMemory)
- OrderedSetGetHead(ActiveGlobalMemorySet))) {
-
- if (context == &TopGlobalMemoryData) {
- /* don't free it and clean it last */
- OrderedElemPop(&TopGlobalMemoryData.elemData);
- } else {
- GlobalMemoryDestroy(context);
- }
- /* what is needed for the top? */
- }
-
- /*
- * Freeing memory here should be safe as this is called
- * only after all modules which allocate in TopMemoryContext
- * have been disabled.
- */
-
- /* step through remaining allocations and log */
- /* AllocSetStep(...); */
-
- /* deallocate whatever is left */
- AllocSetReset(&TopGlobalMemoryData.setData);
- }
-
- processing = false;
- }
-
- Pointer
- MemoryContextAlloc(context, size)
- MemoryContext context;
- Size size;
- {
- AssertState(MemoryContextEnabled);
- AssertArg(MemoryContextIsValid(context));
- AssertArg(SizeIsValid(size));
-
- LogTrap(!AllocSizeIsValid(size), BadAllocSize,
- ((int)"size=%d [0x%x]", size, size));
-
- return (context->method->alloc(context, size));
- }
-
- void
- MemoryContextFree(context, pointer)
- MemoryContext context;
- Pointer pointer;
- {
- AssertState(MemoryContextEnabled);
- AssertArg(MemoryContextIsValid(context));
- AssertArg(PointerIsValid(pointer));
-
- context->method->free_p(context, pointer);
- }
-
- extern SLList PallocDebugList;
- extern SLList *PallocList;
- extern SLList *PfreeList;
- extern int PallocDiffTag;
- extern bool PallocRecord;
- extern bool PallocNoisy;
-
- Pointer
- MemoryContextAlloc_Debug(file, line, context, size)
- String file;
- int line;
- MemoryContext context;
- Size size;
- {
- Pointer p;
- PallocDebugData *d, *d1;
-
- AssertState(MemoryContextEnabled);
- AssertArg(MemoryContextIsValid(context));
- AssertArg(SizeIsValid(size));
-
- LogTrap(!AllocSizeIsValid(size), BadAllocSize,
- ((int)"size=%d [0x%x]", size, size));
-
- p = context->method->alloc(context, size);
- if (PallocRecord) {
- d = (PallocDebugData*)malloc(sizeof(PallocDebugData));
- d->pointer = p;
- d->size = size;
- d->line = line;
- d->file = file;
- d->context = MemoryContextGetName(context);
-
- SLNewNode(&(d->Link));
- SLAddTail(&PallocDebugList, &(d->Link));
- if (PallocDiffTag) {
- d1 = (PallocDebugData*)malloc(sizeof(PallocDebugData));
- d1->pointer = p;
- d1->size = size;
- d1->line = line;
- d1->file = file;
- d1->context = d->context;
- SLNewNode(&(d1->Link));
- SLAddTail(PallocList, &(d1->Link));
- }
- }
- if (PallocNoisy)
- printf("!+ f: %s l: %d p: 0x%x s: %d %s\n",
- file, line, p, size, MemoryContextGetName(context));
- return (p);
- }
-
- void
- MemoryContextFree_Debug(file, line, context, pointer)
- String file;
- int line;
- MemoryContext context;
- Pointer pointer;
- {
- PallocDebugData *d;
-
- AssertState(MemoryContextEnabled);
- AssertArg(MemoryContextIsValid(context));
- AssertArg(PointerIsValid(pointer));
-
- if (PallocRecord) {
- d = (PallocDebugData*)SLGetHead(&PallocDebugList);
- while (d != NULL) {
- if (d->pointer == pointer) {
- SLRemove(&(d->Link));
- break;
- }
- d = (PallocDebugData*)SLGetSucc(&(d->Link));
- }
- if (d != NULL) {
- if (PallocDiffTag)
- SLAddTail(PfreeList, &(d->Link));
- else
- free((char *)d);
- }
- else
- elog(NOTICE, "pfree_remove l:%d f:%s p:0x%x %s",
- line, file, pointer, "** not on list **");
- }
- if (PallocNoisy)
- if (d != NULL) {
- printf("!- f: %s l: %d p: 0x%x s: %d %s\n",
- d->file, d->line, pointer, d->size, context);
- }
- else {
- printf("!- f: %s l: %d p: 0x%x s: ? %s\n",
- file, line, pointer, context);
- }
-
- context->method->free_p(context, pointer);
- }
-
- Pointer
- MemoryContextRealloc(context, pointer, size)
- MemoryContext context;
- Pointer pointer;
- Size size;
- {
- AssertState(MemoryContextEnabled);
- AssertArg(MemoryContextIsValid(context));
- AssertArg(PointerIsValid(pointer));
- AssertArg(SizeIsValid(size));
-
- LogTrap(!AllocSizeIsValid(size), BadAllocSize,
- ((int)"size=%d [0x%x]", size, size));
-
- return (context->method->realloc(context, pointer, size));
- }
-
- String
- MemoryContextGetName(context)
- MemoryContext context;
- {
- AssertState(MemoryContextEnabled);
- AssertArg(MemoryContextIsValid(context));
-
- return (context->method->getName(context));
- }
-
- Size
- PointerGetAllocSize(pointer)
- Pointer pointer;
- {
- AssertState(MemoryContextEnabled);
- AssertArg(PointerIsValid(pointer));
-
- return (PSIZE(pointer));
- }
-
- MemoryContext
- MemoryContextSwitchTo(context)
- MemoryContext context;
- {
- MemoryContext old;
-
- AssertState(MemoryContextEnabled);
- AssertArg(MemoryContextIsValid(context));
-
- old = CurrentMemoryContext;
- CurrentMemoryContext = context;
- return (old);
- }
-
- /*
- * START HERE
- * Add routines to move memory between contexts.
- */
-
- void
- MemoryContextDump(context)
- MemoryContext context;
- {
- context->method->dump(context);
- }
-
- /*
- * DEBUGGING
- */
- void
- DumpMemoryContexts()
- {
- if (!MemoryContextEnabled) {
- printf("!MemoryContextEnabled\n");
- return;
- }
-
- DumpGlobalMemories();
- /*
- * There should also be a standard log interface (DEBUG).
- *
- * Also, add file pcxt for the portal memory context (and gcxt?).
- *
- */
-
-
- }
-
- /*
- * External Functions
- */
-
- GlobalMemory
- CreateGlobalMemory(name)
- String name; /* XXX MemoryContextName */
- {
- GlobalMemory context;
- MemoryContext savecxt;
-
- AssertState(MemoryContextEnabled);
- AssertArg(StringIsValid(name)); /* XXX MemoryContextName */
-
- savecxt = MemoryContextSwitchTo(TopMemoryContext);
-
- context = CreateNode(GlobalMemory);
- context->method = &GlobalContextMethodsData;
- context->name = name; /* assumes name is static */
- AllocSetInit(&context->setData, DynamicAllocMode, (Size)0);
-
- /* link the context */
- OrderedElemPushInto(&context->elemData, ActiveGlobalMemorySet);
-
- MemoryContextSwitchTo(savecxt);
- return (context);
- }
-
- void
- GlobalMemoryDestroy(context)
- GlobalMemory context;
- {
- AssertState(MemoryContextEnabled);
- AssertArg(ExactNodeType(context,GlobalMemory));
- AssertArg(context != &TopGlobalMemoryData);
-
- AllocSetReset(&context->setData);
-
- /* unlink and delete the context */
- OrderedElemPop(&context->elemData);
- #ifdef PALLOC_DEBUG
- MemoryContextFree_Debug(__FILE__, __LINE__,
- TopMemoryContext, (Pointer)context);
- #else
- MemoryContextFree(TopMemoryContext, (Pointer)context);
- #endif
- }
-
- /*
- * PRIVATE
- */
-
- static
- Pointer
- GlobalMemoryAlloc(this, size)
- GlobalMemory this;
- Size size;
- {
- return (AllocSetAlloc(&this->setData, size));
- }
-
- static
- void
- GlobalMemoryFree(this, pointer)
- GlobalMemory this;
- Pointer pointer;
- {
- AllocSetFree(&this->setData, pointer);
- }
-
- static
- Pointer
- GlobalMemoryRealloc(this, pointer, size)
- GlobalMemory this;
- Pointer pointer;
- Size size;
- {
- return (AllocSetRealloc(&this->setData, pointer, size));
- }
-
- static
- String
- GlobalMemoryGetName(this)
- GlobalMemory this;
- {
- return (this->name);
- }
-
- static
- void
- GlobalMemoryDump(this)
- GlobalMemory this;
- {
- GlobalMemory context;
-
- printf("--\n%s:\n", GlobalMemoryGetName(this));
-
- context = (GlobalMemory)OrderedElemGetPredecessor(&this->elemData);
- if (PointerIsValid(context)) {
- printf("\tpredecessor=%s\n", GlobalMemoryGetName(context));
- }
-
- context = (GlobalMemory)OrderedElemGetSuccessor(&this->elemData);
- if (PointerIsValid(context)) {
- printf("\tsucessor=%s\n", GlobalMemoryGetName(context));
- }
-
- AllocSetDump(&this->setData); /* XXX is this right interface */
- }
-
- static
- void
- DumpGlobalMemories()
- {
- GlobalMemory context;
-
- context = (GlobalMemory)OrderedSetGetHead(&ActiveGlobalMemorySetData);
-
- while (PointerIsValid(context)) {
- GlobalMemoryDump(context);
-
- context = (GlobalMemory)OrderedElemGetSuccessor(
- &context->elemData);
- }
- }
-
- /*
- * MemoryContextIsValid(context) is now a macro in mnodes.h -cim 4/27/91
- */
-
- void
- PrintGlobalMemory(foo)
- GlobalMemory foo;
- {
- }
-